package com.woniuxy.kaer.shop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.kaer.commons.util.Data;
import com.woniuxy.kaer.commons.util.PageInfo;
import com.woniuxy.kaer.form.PageForm;
import com.woniuxy.kaer.param.RefundParam;
import com.woniuxy.kaer.redis.util.RedisKey;
import com.woniuxy.kaer.shop.config.WebSocketServer;
import com.woniuxy.kaer.shop.mapper.ProductMapper;
import com.woniuxy.kaer.shop.mapper.ProductOrderDataMapper;
import com.woniuxy.kaer.shop.mapper.ProductOrderMapper;
import com.woniuxy.kaer.shop.model.Product;
import com.woniuxy.kaer.shop.model.ProductOrder;
import com.woniuxy.kaer.shop.model.ProductOrderData;
import com.woniuxy.kaer.shop.model.RefundRequests;
import com.woniuxy.kaer.shop.mapper.RefundRequestsMapper;
import com.woniuxy.kaer.shop.service.RefundRequestsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.kaer.user.UserInfoFeignClient;
import com.woniuxy.kaer.user.form.UpdatePointForm;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 郭建东
 * @since 2025年02月17日
 */
@Service
public class RefundRequestsServiceImpl extends ServiceImpl<RefundRequestsMapper, RefundRequests> implements RefundRequestsService {

    @Resource
    private ProductOrderMapper productOrderMapper;

    @Resource
    private RefundRequestsMapper refundRequestsMapper;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private AlipayClient alipayClient;

    @Resource
    private UserInfoFeignClient userInfoFeignClient;

    @Resource
    private ProductOrderDataMapper productOrderDataMapper;

    @Resource
    private ProductMapper productMapper;

    @Resource
    private WebSocketServer webSocketServer;

    @Override
    public void applyRefund(RefundParam param, Integer userId) throws Exception {
        // 查询订单信息
        ProductOrder productOrder = productOrderMapper.selectById(param.getProductOrderId());
        if(productOrder==null){
            throw new Exception("订单不存在");
        }
        System.out.println(userId);
        if(productOrder.getUserId()!=userId){
            throw new Exception("订单不属于当前用户");
        }
        if(productOrder.getPayState()!= Data.ORDER_PAY_STATE_PAYED){
            throw new Exception("订单还未支付");
        }
        if(productOrder.getRefundState()== Data.ORDER_STATE_REFUNDED){
            throw new Exception("订单已退款");
        }
        QueryWrapper<RefundRequests> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_order_id",param.getProductOrderId());
        Long count = refundRequestsMapper.selectCount(queryWrapper);
        System.out.println(count);
        if(refundRequestsMapper.selectCount(queryWrapper)>0){
            throw new Exception("订单已申请退款,请勿重复申请");
        }
        RefundRequests requests = BeanUtil.toBean(param, RefundRequests.class);
        requests.setRefundReviewState(Data.REFUND__STATE_NORMAL);
        requests.setCreateTime(LocalDateTime.now());
        String refundId ="R"+"-"+ UUID.randomUUID().toString().replace("-","").substring(0, 10);
        requests.setRefundId(refundId);
        requests.setProductOrderId(param.getProductOrderId());
        requests.setAmount(productOrder.getTotal());
        refundRequestsMapper.insert(requests);
//        // 修改订单状态(退款申请）
//        productOrder.setOrderState(Data.ORDER_STATE_REFUND_APPLY);
//        productOrderMapper.updateById(productOrder);
        String message = "订单 " + param.getProductOrderId() + "申请退款,请及时处理";
        WebSocketServer.sendInfo(message, "1");

    }

    @Override
    public void handleRefundApply(String refundId, Integer state) throws Exception {
        RLock lock = redissonClient.getFairLock(RedisKey.LOCK_APPLYID(refundId));
        try{
            lock.lock();
            RefundRequests refundRequests = refundRequestsMapper.selectById(refundId);
            if(refundRequests==null){
                throw new Exception("退款申请不存在");
            }
            if(refundRequests.getRefundReviewState()!=Data.REFUND__STATE_NORMAL){
                throw new Exception("退款申请已被处理");
            }
            refundRequests.setRefundReviewState(state);
            //处理退款时间
            refundRequests.setUpdateTime(LocalDateTime.now());
            refundRequestsMapper.updateById(refundRequests);
            ProductOrder productOrder = productOrderMapper.selectById(refundRequests.getProductOrderId());
            if (state==Data.REFUND__STATE_SUCCESS) {
                //同意申请退款
                productOrder.setOrderState(Data.ORDER_STATE_REFUNDED);
                //将订单编号保存到消息队列中
                rabbitTemplate.convertAndSend("wait-exchange","refund",productOrder.getProductOrderId());
            }else{
                productOrder.setOrderState(Data.ORDER_STATE_REFUND_FAIL);
            }
            productOrderMapper.updateById(productOrder);
        }finally {
            lock.unlock();
        }
    }

    @Override
    public void handleRefund(String refundId)throws Exception {
        RefundRequests refundRequests = refundRequestsMapper.selectById(refundId);
        if (refundRequests == null) {
            System.err.println("退款申请不存在，申请 ID: " + refundId);
            return;
        }

        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizContent("{\"out_trade_no\":\"" + refundRequests.getProductOrderId() + "\","
                + "\"refund_amount\":\"" + refundRequests.getAmount().toString() + "\","
                + "\"refund_reason\":\"" + refundRequests.getRefundReason() + "\"}");

        try {
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                // 退款成功，更新退款状态
                refundRequests.setRefundReviewState(Data.REFUND__STATE_SUCCESS);
                refundRequests.setUpdateTime(LocalDateTime.now());
                refundRequestsMapper.updateById(refundRequests);
                //更新订单状态
                ProductOrder productOrder = productOrderMapper.selectById(refundRequests.getProductOrderId());
                productOrder.setOrderState(Data.ORDER_STATE_REFUNDED);
                productOrderMapper.updateById(productOrder);
                System.out.println("退款成功，申请 ID: " + refundId);
                //恢复商品库存
                QueryWrapper<ProductOrderData> wrapper = new QueryWrapper<>();
                wrapper.eq("product_order_id", refundRequests.getProductOrderId());
                List<ProductOrderData> productOrderDatas = productOrderDataMapper.selectList(wrapper);
                for (ProductOrderData productOrderData : productOrderDatas) {
                    Product product = productMapper.selectById(productOrderData.getProductId());
                    product.setInventory(product.getInventory() + productOrderData.getProductNum());
                    productMapper.updateById(product);
                }
                //扣除退款金额的积分
                UpdatePointForm form = new UpdatePointForm();
                form.setUserId(productOrder.getUserId());
                form.setPointChangeNum(-Integer.valueOf(refundRequests.getAmount().toString()));
                userInfoFeignClient.updatePoint(form);
            } else {
                // 退款失败，更新退款状态
                refundRequests.setRefundReviewState(Data.REFUND__STATE_FAIL);
                refundRequests.setUpdateTime(LocalDateTime.now());
                refundRequestsMapper.updateById(refundRequests);
                //更新订单状态
                ProductOrder productOrder = productOrderMapper.selectById(refundRequests.getProductOrderId());
                productOrder.setOrderState(Data.ORDER_STATE_REFUND_FAIL);
                productOrderMapper.updateById(productOrder);
                System.err.println("退款失败，申请 ID: " + refundId + ", 错误码: " + response.getCode() + ", 错误信息: " + response.getMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            // 退款异常，更新退款状态
            refundRequests.setRefundReviewState(Data.REFUND__STATE_FAIL);
            refundRequestsMapper.updateById(refundRequests);
            System.err.println("退款异常，申请 ID: " + refundId + ", 异常信息: " + e.getMessage());
        }
    }

    @Override
    public PageInfo searchRefund(PageForm form) throws Exception {
        if(form.getPageNum()==null || form.getPageNum()==0){
            throw new Exception("页码不能为空");
        }if(form.getPageSize()==null || form.getPageSize()==0){
            throw new Exception("页大小不能为空");
        }
        QueryWrapper<RefundRequests> queryWrapper = new QueryWrapper<>();
        Page page = refundRequestsMapper.selectPage(new Page<>(form.getPageNum(), form.getPageSize()), queryWrapper);
        PageInfo refundRequestsPageInfo = new PageInfo(page);
        return refundRequestsPageInfo;
    }
}
